﻿var _keys = {
    backSpace: 8,
    bs: 8,
    comma: 188,
    pcomma: 110,
    dash: 189,
    dot: 190,
    decimalSep: 110,
    del: 46,
    arrowLeft: 37,
    arrowRight: 39,
    n0: 48,
    n9: 57,
    pn0: 96,
    pn9: 105,
    home: 36,
    end: 35,
    tab: 9,
    enter: 13,
    esc: 27,
    fowardSlash: 191,
    pfowardSlash: 193,
    backSlash: 220,
    pbackSlash: 226
};

var utils = {
    padL: function (value, length, fillChar)
    {
        var result = value.toString();
        fillChar = fillChar || " ";
        while (result.length < length)
        {
            result = fillChar + result;
        }
        if (result.length > length)
            result = result.substr(0, length);
        return result;
    },

    padR: function (value, length, fillChar)
    {
        var result = value.toString();
        fillChar = fillChar || " ";
        while (result.length < length)
        {
            result = result + fillChar;
        }
        if (result.length > length)
            result = result.substr(0, length);
        return result;
    },

    padNumber: function (value, length)
    {
        return this.padL((value || "").toString(), length, '0');
    },

    stuffChars: function (source, picture, reverse, removedChar)
    {
        var result = "";
        var nextChar = "";
        var sourceIndex = reverse ? source.toString().length - 1 : 0;
        var pictIndex = reverse ? picture.toString().length - 1 : 0;
        var inc = reverse ? -1 : 1;

        while (pictIndex > -1
                && pictIndex < picture.toString().length
                && sourceIndex < source.toString().length)
        {
            //ler a picture e determinar de onde tirar o caracter
            var pictChar = picture.toString().substr(pictIndex, 1);
            nextChar = '';
            if (pictChar.toLowerCase() == "x")
            {
                if (sourceIndex > -1)
                {
                    nextChar = source.toString().substr(sourceIndex, 1);
                    sourceIndex += inc;
                }
            }
            else if (pictChar.toLowerCase() == "<")
            {
                nextChar = removedChar;
                sourceIndex += inc;
            }
            else if (sourceIndex > -1)
                nextChar = pictChar;

            //adicionar no resultado
            if (reverse)
                result = nextChar + result;
            else
                result += nextChar;

            //incrementar os indices
            pictIndex += inc;
        }
        return result;
    },

    repl: function (ch, times)
    {
        var res = "";
        while (res.length < times) res += ch;
        return res;
    },

    formatCurrency: function (value, moneySymb)
    {
        var str = value.toString();
        var pd = str.lastIndexOf('.', str.length - 1);
        if (pd == -1)
        {
            str += ".00";
        }
        else if (pd <= str.length - 3)
        {
            str = str.substr(0, pd + 3);
        } else
        {
            str = str + this.repl('0', str.length - pd - 1);
        }

        var r = this.stuffChars(this.filterDigits(str), "x.xxx.xxx,xx", true);
        if (moneySymb)
            return "R$ " + r;
        return r;
    },

    formatNumber: function (value)
    {
        return this.stuffChars(value || 0, "xxx.xxx.xxx", true);
    },

    filterDigits: function (value)
    {
        return this.filterChars(value ? value : "", "0123456789");
    },

    filterChars: function (str, chars)
    {
        var result = "";
        for (var i = 0; i < str.toString().length; i++)
        {
            var chr = str.toString().substr(i, 1);
            if (chars.toString().indexOf(chr) > -1)
            {
                result = result + chr;
            }
        }
        return result;
    },

    createTimer: function (callback, interval)
    {
        return new __createTimer(callback, interval);

        function __createTimer(callback, interval)
        {
            this.callback = callback;
            this.interval = interval || 1000;
            this.active = false;
            this.start = function (_interval)
            {
                if (!this.active)
                {
                    this.interval = _interval || this.interval;
                    this.active = true;
                    this.__setTimer(this);
                }
            }
            this.stop = function ()
            {
                this.active = false;
            }
            this.__setTimer = function (timer)
            {
                if (this.active)
                    setTimeout(function () { timer.__executeTimer(timer); }, timer.interval);
            }
            this.__executeTimer = function (timer)
            {
                if (timer.callback)
                    timer.callback();
                timer.__setTimer(timer);
            }
        }
    },

    timeStr: function (time)
    {
        time = time || new Date();
        return this.padNumber(time.getHours(), 2)
            + ":" + this.padNumber(time.getMinutes(), 2)
            + ":" + this.padNumber(time.getSeconds(), 2);
    },

    utcTimeStr: function (time)
    {
        time = time || new Date();
        return this.padNumber(time.getUTCHours(), 2)
            + ":" + this.padNumber(time.getUTCMinutes(), 2)
            + ":" + this.padNumber(time.getUTCSeconds(), 2);
    },

    round: function (number, decimalPlaces)
    {
        return Math.round(number * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
    },

    parseInt: function (value)
    {
        //retirar os zeros da esquerda, caso contrario a VM do javascript considera o numero como zero.
        value = value || "";
        if (!value.length) return 0;
        while (value.substr(0, 1) == "0")
            value = value.substr(1);
        value = this.filterDigits(value);
        return value.length ? parseInt(value) : 0;
    },

    parseFloat: function (value)
    {
        //procurar pelo ponto decimal.
        value = value.toString();
        var pos = Math.max(value.lastIndexOf('.'), value.lastIndexOf(','));
        var intPart, decPart;
        if (pos > -1)
        {
            intPart = value.substring(0, pos);
            decPart = value.substring(pos + 1);
        }
        else
        {
            intPart = value;
            decPart = "0";
        }
        return parseFloat(intPart
            .replace(/,/g, "")
            .replace(/\./g, "")
            .replace("R$", "")
            .replace(" ", "") + "." + decPart);
    },

    convertToFloat: function (value)
    {
        var result = this.parseFloat(value);
        if (result == NaN)
            return 0;
        return result;
    },

    getEventKey: function (event)
    {
        event = event || window.event;
        return event.keyCode || event.which || event.charCode;
    },

    setEventKey: function (event, keyCode)
    {
        event = event || window.event;
        event.charCode = event.keyCode = event.which = undefined;
    },

    clearEventKey: function (event)
    {
        this.setEventKey(event, undefined);
    },

    preventEventDefault: function (event)
    {
        e = event;
        if (e.preventDefault)
        { //standart browsers
            e.preventDefault()
        } else
        { // internet explorer
            e.returnValue = false
        }
    },

    keys: _keys,

    isDigitKey: function (keyCode)
    {
        return (keyCode >= _keys.n0 && keyCode <= _keys.n9)
         || (keyCode >= _keys.pn0 && keyCode <= _keys.pn9);
    },

    isDecimalSep: function (keyCode)
    {
        return keyCode == _keys.dot || keyCode == _keys.comma || keyCode == _keys.pcomma;
    },

    isSlashKey: function (keyCode)
    {
        return keyCode == _keys.backSlash || keyCode == _keys.fowardSlash
        || keyCode == _keys.pbackSlash || keyCode == _keys.pfowardSlash;
    },

    isModifierKey: function (keyCode)
    {
        return keyCode == _keys.del || keyCode == _keys.backSpace;
    },

    isSpecialKeyPressed: function (event)
    {
        return event.altKey || event.ctrlKey || event.shiftKey || event.metaKey;
    },

    getFloatParts: function (number)
    {
        var result = { integer: 0, decimal: 0 };
        if (number)
        {
            var str = number.toString();
            var pos = str.lastIndexOf('.');
            if (pos > -1)
            {
                result.integer = utils.parseInt(str.substring(0, pos));
                var dec = str.substr(pos + 1, 2).trim();
                result.decimal = utils.parseInt(dec);
                if (dec.length == 1)
                    result.decimal = result.decimal * 10;
            }
            else
                result.integer = number;
        }
        return result;
    },

    isNavigationKey: function (keyCode)
    {
        return (keyCode == _keys.comma)
            || (keyCode == _keys.dash)
            || (keyCode == _keys.dot)
            || (keyCode == _keys.arrowLeft)
            || (keyCode == _keys.arrowRight)
            || (keyCode == _keys.home)
            || (keyCode == _keys.end)
            || (keyCode == _keys.backSpace)
            || (keyCode == _keys.tab)
            || (keyCode == _keys.pcomma)
            || (keyCode == _keys.del)
    },

    splitDateString: function (str)
    {
        var temp = (str || "").toString().split(/(\s|\/|:|-|\.)/);
        var tokens = [];
        //diferença no regexp do IE para o WebKit, vou usar apenas os items que sejam numero
        for (var i = 0; i < temp.length; i++)
        {
            if (utils.filterDigits(temp[i]).length)
                tokens.push(temp[i]);
        }

        parts = {
            year: this.parseInt(tokens[2]),
            month: this.parseInt(tokens[1]),
            day: this.parseInt(tokens[0])
        };
        if (parts.year.toString().length <= 2)
            parts.year += (parts.year < 50 ? 2000 : 1900);
        parts.hour = this.parseInt(tokens[3]);
        parts.minute = this.parseInt(tokens[4]);
        parts.second = this.parseInt(tokens[5]);
        return parts;
    },

    joinDateParts: function (parts, addTime)
    {
        var result = this.padNumber(parts.day, 2)
                 + "/" + this.padNumber(parts.month, 2)
                 + "/" + this.padNumber(parts.year, 4);
        if (addTime == "short" || addTime !== false)
            result += " " + this.padNumber(parts.hour, 2)
                 + ":" + this.padNumber(parts.minute, 2);
        if (addTime !== "short" && addTime !== false)
            result += ":" + this.padNumber(parts.second, 2);
        return result;
    },

    formatDateString: function (str, addTime)
    {
        return this.joinDateParts(this.splitDateString(str), addTime);
    },

    getDateParts: function (str)
    {
        var i = 0;
        var aux = 0;
        var parts = {};
        //dia
        i = str.indexOf("/");
        parts["day"] = str.substr(0, i);
        // mes
        aux = i + 1;
        i = str.indexOf("/", aux);
        parts["month"] = str.substr(aux, i - aux);
        //ano
        aux = i + 1;
        i = str.indexOf(" ", aux);
        if (i < aux)
        {
            parts["year"] = str.substr(aux, str.length - aux);
            parts["hour"] = "0";
            parts["minutes"] = "0";
            parts["seconds"] = "0";
        }
        else
        {
            parts["year"] = str.substr(aux, i - aux);
            //hora
            aux = i + 1;
            i = str.indexOf(":", aux);
            if (i < aux)
            {
                parts["hour"] = str.substr(aux, str.length - aux);
                parts["minutes"] = "0";
                parts["seconds"] = "0";
            } else
            {
                parts["hour"] = str.substr(aux, i - aux);
                //minutos
                aux = i + 1;
                i = str.indexOf(":", aux);
                if (i < aux)
                {
                    parts["minutes"] = str.substr(aux, i - aux);
                    parts["seconds"] = "0";
                }
                else
                {
                    parts["minutes"] = str.substr(aux, i - aux);
                    aux = i + 1;
                    if (aux >= str.length)
                        parts["seconds"] = "0";
                    else
                        parts["seconds"] = str.substr(aux, str.length - aux);
                }
            }
        }
        var year = parts["year"] || "";
        if (year.length <= 2)
        {
            var iyear = utils.parseInt(year);
            year = (iyear > 50 ? "19" : "20") + utils.padNumber(iyear, 2);
        }
        parts["year"] = year;
        return parts;
    },

    datePartsToString: function (parts, addTime)
    {
        var result = this.padNumber(parts.day, 2)
                 + "/" + this.padNumber(parts.month, 2)
                 + "/" + this.padNumber(parts.year, 4);
        if (addTime !== false)
            result += " " + this.padNumber(parts.hour, 2)
                 + ":" + this.padNumber(parts.minutes, 2)
                 + ":" + this.padNumber(parts.seconds, 2);
        return result;
    },

    dateDiff: function (date1, date2)
    {
        return date2.getTime() - date1.getTime();
    },

    normalizeDateString: function (dateString)
    {
        return this.datePartsToString(this.getDateParts(dateString));
    },

    $s4: function ()
    {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    },

    guid: function ()
    {
        var d = new Date().getTime().toString(16);
        return (this.$s4()
            + this.$s4()
            + this.$s4()
            + d.substring(d.length - 8)
            + this.$s4()
            + this.$s4()
            + this.$s4());
    }

};

//prototype para String
String.prototype.trim = function ()
{
    return this.replace(/^\s+|\s+$/g, '');
};

String.prototype.ltrim = function ()
{
    return this.replace(/^\s+/, '');
};

String.prototype.rtrim = function ()
{
    return this.replace(/\s+$/, '');
};